package com.app.store.controller;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.util.*;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.*;
import com.app.mail.service.MailService;
import com.app.store.dto.AppUtil;
import com.app.store.dto.AppVersionDto;
import com.app.store.model.AppVersion;
import com.app.store.service.StoreService;
import com.app.sysmodule.exception.ServiceException;
import com.app.sysmodule.excuteUtil.ThreadPoolExecutor;
import com.app.sysmodule.httpcommon.service.HttpCommonService;
import com.app.sysmodule.reponse.JsonResult;
import com.app.sysmodule.utils.AcewillBase64;
import com.app.sysmodule.utils.JsonData;
import com.app.sysmodule.utils.PropertyUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.Callback.CalbackBodyType;


/**
 * Created by song on 2017/11/28.
 */
@Controller
@RequestMapping("/app")
public class StoreController {
    private static Logger log = Logger.getLogger(StoreController.class);
    @Autowired
    private StoreService storeService;
    @Autowired
    HttpCommonService httpCommonService;
    @Autowired
    MailService mailService;

    /**
     * 供应链获取下载主页
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/homePage",method = RequestMethod.POST)
    public JsonResult homePage(HttpServletRequest request,HttpServletResponse response){
        JsonResult jsonResult = new JsonResult();
        try {
            JSONObject jsonObject = JsonData.getRequestBodyData(request);
            log.info("获取下载主页请求数据："+jsonObject);
            String version = (String) jsonObject.get("version");
            String source = (String) jsonObject.get("source");
            if(StringUtils.isNotEmpty(version) && StringUtils.isNotEmpty(source)){
                String url = PropertyUtils.getProperty("download_url");
                Map<String,Object> map = new HashMap<String, Object>();
                String downUrl = url+"homePage.jsp?version="+version+"&source="+source;
                map.put("url",downUrl);
                jsonResult.setCode(0);
                jsonResult.setMsg("请求成功");
                jsonResult.setData(map);
            }else {
                jsonResult.setCode(1);
                jsonResult.setMsg("请求参数有误");
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setCode(1);
            jsonResult.setMsg("请求失败");
        }
        return jsonResult;
    }
    /**
     * 根据服务端版本号 手机设备类型返回下载页
     * type : 01 ios   02 安卓
     */
    /**
     * 供应链获取app下载页
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/downInfo",method = RequestMethod.POST)
    public JsonResult downInfo(HttpServletRequest request,HttpServletResponse response){
        JsonResult jsonResult = new JsonResult();
        try {
            JSONObject jsonObject = JsonData.getRequestBodyData(request);
            log.info("获取下载主页请求数据："+jsonObject);
            String version = (String) jsonObject.get("version");
            String type = (String) jsonObject.get("type");
            String source = (String) jsonObject.get("source");
            if(StringUtils.isNotEmpty(version) && StringUtils.isNotEmpty(type) && StringUtils.isNotEmpty(source)){
                AppVersionDto dto = storeService.downInfo(version.substring(1,version.length()),type,source);
                jsonResult.setCode(0);
                jsonResult.setMsg("请求成功");
                jsonResult.setData(dto);
                log.info("获取下载主页返回数据："+jsonResult);
            }else {
                jsonResult.setCode(1);
                jsonResult.setMsg("请求参数有误");
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setCode(1);
            jsonResult.setMsg("请求失败");
        }
        return jsonResult;
    }

    /**
     * 获取app版本  判断是否需要升级
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getAppVersion",method = RequestMethod.POST)
    public JsonResult getAppVersion(HttpServletRequest request, HttpServletResponse response){
        JsonResult jsonResult = new JsonResult();
        String type = request.getHeader("section");//设备类型
        String appVersion = request.getHeader("clientversion");//app设备版本号
        Map<String, Object> map = new HashMap<String, Object>();
        String serverVersion = null;
        try{
            //根据公司id获取服务端版本号（jumpserver接口）
            JSONObject jsonObject = JsonData.getRequestBodyData(request);
            String company = (String) jsonObject.get("company");
            String url = PropertyUtils.getProperty("scm_url");
            log.info("type:"+type+"------appVersion:"+appVersion);
            Map<String,Object> map1 = new HashMap<String, Object>();
            map1.put("appId",company.toLowerCase());
            JSONObject js = httpCommonService.handleMap(url+"SuperApp/checkAppid","SuperApp/checkAppid",map1,null);
            log.info("获取供应链服务端版本："+js);
            if(null != js){
                Boolean flag = (Boolean)js.get("success");
                if(flag){
                    JSONObject js1 = (JSONObject) js.get("data");
                    String bc_version = (String) js1.get("bc_version");
                    if(StringUtils.isNotEmpty(bc_version)){
                        serverVersion =  bc_version.substring(1,bc_version.length());
                    }
                }
            }
            if(StringUtils.isNotEmpty(serverVersion)){
                AppVersionDto ver = storeService.getVersion(type,appVersion,serverVersion);
                if(null != ver) {
                    jsonResult.setData(ver);
                    jsonResult.setCode(0);
                    jsonResult.setMsg("请求成功");
                }else{
                    jsonResult.setData(ver);
                    jsonResult.setCode(0);
                    jsonResult.setMsg("请求成功");
                }
            }else {
                jsonResult.setCode(1);
                jsonResult.setMsg("请求失败");
            }
        }catch (Exception e){
            log.error(e.getMessage());
            jsonResult.setCode(1);
            jsonResult.setMsg("请求失败");
        }
        return jsonResult;
    }

    /**
     * 获取供应链服务端url地址
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getServerUrl",method = RequestMethod.POST)
    public JsonResult getServerUrl(HttpServletRequest request, HttpServletResponse response){
        JsonResult jsonResult = new JsonResult();
        Map<String, Object> map = new HashMap<String, Object>();
        try{
            JSONObject jsonObject = JsonData.getRequestBodyData(request);
            log.info("app获取服务端地址请求参数："+jsonObject);
            String company = (String) jsonObject.get("company");
            String url = PropertyUtils.getProperty("scm_url");
            Map<String,Object> map1 = new HashMap<String, Object>();
            if(StringUtils.isNotEmpty(company)){
                map1.put("appId",company.toLowerCase());
            }

            JSONObject js = httpCommonService.handleMap(url+"SuperApp/checkAppid","SuperApp/checkAppid",map1,null);
            log.info("获取供应链服务端url地址："+js);
            if(null != js && js.size()>0){
                Boolean flag = (Boolean)js.get("success");
                if(flag){
                    JSONObject js1 = (JSONObject) js.get("data");
                    String bc_chainurl = (String) js1.get("bc_chainurl");
                    if(StringUtils.isNotEmpty(bc_chainurl)){
                        Map<String,Object> map2 = new HashMap<String, Object>();
                        map2.put("url",bc_chainurl);
                        jsonResult.setData(map2);
                        jsonResult.setCode(0);
                        jsonResult.setMsg("请求成功");
                    }else {
                        jsonResult.setCode(1);
                        jsonResult.setMsg("请求参数有误");
                    }
                }else {
                    jsonResult.setCode(1);
                    jsonResult.setMsg((String)js.get("msg"));
                }
            }else {
                jsonResult.setCode(1);
                jsonResult.setMsg("服务器无法连接，请联系管理员");
            }
        }catch (Exception e){
            log.error(e.getMessage());
            jsonResult.setCode(1);
            jsonResult.setMsg("请求失败");
        }
        return jsonResult;
    }

    /**
     * 上传app
     * @param file
     * @param request
     * @return
     */
    @RequestMapping(value = "/fileUpload",method = RequestMethod.POST)
    public ModelAndView  fileUpload1(@RequestParam("file") MultipartFile file,@RequestParam("serverVersion") final String serverVersion,@RequestParam("isUpgrade") String isUpgrade,@RequestParam("appVersion") String appVersion,HttpServletRequest request){
        ModelAndView errorModelAndView = new ModelAndView("error/error");
        ModelAndView successModelAndView = new ModelAndView("upload");
        HttpSession session = request.getSession();
        String username = (String) session.getAttribute("username");
        if(StringUtils.isEmpty(username)){
            ModelAndView loginView = new ModelAndView("redirect:/login/login.jsp");
            loginView.addObject("errorMsg","请求超时，请重新登录");
            return loginView;
        }
        if(StringUtils.isEmpty(serverVersion)){
            errorModelAndView.addObject("result","服务端版本号不能为空");
            return errorModelAndView;
        }
        if(StringUtils.isEmpty(appVersion)){
            errorModelAndView.addObject("result","app版本号不能为空");
            return errorModelAndView;
        }
        InputStream is = null;
        if (!file.isEmpty()) {
            try {
                String[] extensions = file.getOriginalFilename().split("\\.");
                String fileExtension = extensions[extensions.length - 1];//获取文件扩展名
                CommonsMultipartFile cFile = (CommonsMultipartFile) file;
                DiskFileItem fileItem = (DiskFileItem) cFile.getFileItem();
                is = fileItem.getInputStream();
                String downLoadPath = PropertyUtils.getProperty("package_path");
                String path = null;
                String type = null;
                String version = null;
                String fileSize = null;
                String fileName = null;
                String downFileUrl = null;
                String remark = null;
                String remarkStr = request.getParameter("remark");
                String isJenkings = request.getParameter("is_jenkings");
                log.info("remarkStr:"+remarkStr);
                if(null != isJenkings){
                   remarkStr  = AcewillBase64.decode(remarkStr, "");
                    log.info("remarkStr:"+remarkStr);
                }
                remark = remarkStr;
                log.info("remark:"+remark);
                //阿里云
                final String bucketName = PropertyUtils.getProperty("aliyun_bucketName");
                final String endpoint = PropertyUtils.getProperty("aliyun_endpoint");
                String host = PropertyUtils.getProperty("aliyun_host");
                final String accessKeyId = PropertyUtils.getProperty("aliyun_accessKeyId");
                final String accessKeySecret = PropertyUtils.getProperty("aliyun_accessKeySecret");
                String downloanUrl = PropertyUtils.getProperty("download_url");
                String appStoreUrl = PropertyUtils.getProperty("app_store_url");
                Boolean flag = false;//文件是否存在标志
                if(StringUtils.isNotEmpty(fileExtension) && fileExtension.toLowerCase().equals("ipa")){
                    //ios
                    Map<String, Object> infoPlist = AppUtil.analyzeIpa(is);
                    String packageName = (String) infoPlist.get("CFBundleIdentifier");//获取包名
                    version = (String) infoPlist.get("CFBundleShortVersionString");//获取版本号
                    fileSize = FormetFileSize(file.getSize());//文件大小
                    fileName = (String) infoPlist.get("CFBundleDisplayName");
                    type = "01";
                    String packagerUrl = "https://"+bucketName+"."+host+"/"+version+"/CRM_YUN.ipa";//ipa文件下载地址
                    downFileUrl = appStoreUrl + downloanUrl +"app-download/"+version+"/manifest.plist";
                    if(!appVersion.equals(version)){
                        errorModelAndView.addObject("result","请输入app正确版本号"+"---当前package版本号为:"+version);
                        return errorModelAndView;
                    }
                    //保存数据库
                    if(StringUtils.isNotEmpty(type) && StringUtils.isNotEmpty(version)){
                        flag  = storeService.saveAppVersion(version,type,fileSize,fileName,isUpgrade,serverVersion,remark,downFileUrl,username);
                    }
                    if(!flag){
                        errorModelAndView.addObject("result","app版本已经存在"+"---package version:"+version);
                        return errorModelAndView;
                    }
                    OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
                    ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
                    ossClient.putObject(bucketName,version+"/CRM_YUN.ipa",fileItem.getInputStream());
                    ossClient.shutdown();
                    storeService.generatePlistFile(packageName,version,packagerUrl,downLoadPath);//生成manifest.plist文件
                }else if(StringUtils.isNotEmpty(fileExtension) && fileExtension.toLowerCase().equals("apk")){
                    //android 获取安卓版本号
                    String filename = file.getOriginalFilename();
                    String[] str = filename.split("-");
                    List list = Arrays.asList(str);
                    if(null != list && list.size()>0){
                        String versionStr = (String) list.get(2);
                        if(null != versionStr){
                            if(versionStr.contains("V".toLowerCase())){
                                version = versionStr.substring(1,versionStr.length());
                            }else {
                                version = versionStr;
                            }
                        }
                    }
                    fileSize = FormetFileSize(file.getSize());//文件大小
                    type = "02";
                    fileName="易企安卓版";
                    if(!appVersion.equals(version)){
                        errorModelAndView.addObject("result","请输入app正确版本号"+"---当前package版本号为:"+version);
                        return errorModelAndView;
                    }
                    //安卓下载地址
                    downFileUrl = "https://"+bucketName+"."+host+"/"+version+"/"+"yiqi-android.apk";
                    //保存数据库
                    if(StringUtils.isNotEmpty(type) && StringUtils.isNotEmpty(version)){
                        flag = storeService.saveAppVersion(version,type,fileSize,fileName,isUpgrade,serverVersion,remark,downFileUrl,username);
                    }
                    if(!flag){
                        errorModelAndView.addObject("result","app版本已经存在"+"---package version:"+version);
                        return errorModelAndView;
                    }
                    OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
                    ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
                    ossClient.putObject(bucketName,version+"/yiqi-android.apk",is);
                    ossClient.shutdown();
                }else {
                    errorModelAndView.addObject("result","请上传正确文件");
                    return errorModelAndView;
                }

                //异步发送邮件
                final String downUrl = PropertyUtils.getProperty("download_url") + "homePage.jsp?version=" + serverVersion + "&source=scm";
                final String pathQrcode = request.getServletContext().getRealPath("/");
                final String finalVersion = version;
                final String finalFileSize = fileSize;
                final String finalType = type;
                final Integer num = 5;//默认同一个服务端版本对应app安装包只留5个
                final String finalRemark = remark;
                ThreadPoolExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ");
                            Date date=new Date();
                            String time = sdf.format(date);
                            //异步发送邮件
                            mailService.sendMail(finalVersion, serverVersion, finalFileSize, time, finalRemark, downUrl, finalType, pathQrcode,bucketName);
                            //异步删除多余app安装包
                            storeService.deleteOss(endpoint,accessKeyId,accessKeySecret,bucketName,serverVersion.substring(1,serverVersion.length()),finalType,num);
                        } catch (ServiceException e) {
                            e.printStackTrace();
                            log.error("发送邮件失败"+e.getMessage());
                        }
                    }
                });
                successModelAndView.addObject("result",downUrl);
                log.info(" app 上传成功："+downUrl);
                return successModelAndView;
            } catch (Exception e) {
                e.printStackTrace();
                log.error("上传失败："+e.getMessage());
                errorModelAndView.addObject("result","上传失败");
                return errorModelAndView;
            }finally {
                if(null != is){
                    try {
                        is.close();
                    } catch (IOException e) {
                        log.error("");
                        e.printStackTrace();
                    }
                }
            }
        }else {
            errorModelAndView.addObject("result","上传文件不能为空");
            return errorModelAndView;
        }
    }
    /**
     * 获取文件大小  将byte转化为kb/mb/gb
     * @param size
     * @return
     */
    public String FormetFileSize(long size) {//转换文件大小
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        if (size < 1024) {
            fileSizeString = df.format((double) size) + "B";
        } else if (size < 1048576) {
            fileSizeString = df.format((double) size / 1024) + "KB";
        } else if (size < 1073741824) {
            fileSizeString = df.format((double) size / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) size / 1073741824) +"GB";
        }
        return fileSizeString;
    }
    /**
     * 获取最新下载页面
     * 获取最新app版本下载页
     * ios：01  android:02
     */
    @RequestMapping(value = "/getNewest", method=RequestMethod.GET)
    @ResponseBody
    public ModelAndView gerNewest(HttpServletRequest request, HttpServletResponse response) {
        ModelAndView errorModelAndView = new ModelAndView("error/error");
        ModelAndView successModelAndView = new ModelAndView("upload");
        String type = request.getParameter("type");
        if (StringUtils.isNotEmpty(type)) {
            String source = "scm";
            try {
                AppVersion appVersion = storeService.getNewByType(type, source);
                if (null != appVersion) {
                    String downUrl = PropertyUtils.getProperty("download_url") + "homePage.jsp?version=V" + appVersion.getServerVersion() + "&source=scm";
                    successModelAndView.addObject("result", downUrl);
                    return successModelAndView;
                } else {
                    errorModelAndView.addObject("result", "请求失败,请联系管理员");
                    return errorModelAndView;
                }
            } catch (Exception e) {
                e.printStackTrace();
                errorModelAndView.addObject("result", "请求失败,请联系管理员");
                return errorModelAndView;
            }
        } else {
            errorModelAndView.addObject("result", "请求失败,请联系管理员");
            return errorModelAndView;
        }
    }
    /**
     * 获取最新下载页面
     * 获取最新app版本下载页
     * ios：01  android:02
     */
    @RequestMapping(value = "/getNewest01", method=RequestMethod.POST)
    @ResponseBody
    public JsonResult gerNewest01(HttpServletRequest request, HttpServletResponse response) {
        JsonResult jsonResult = new JsonResult();
        JSONObject jsonObject = JsonData.getRequestBodyData(request);
        String type = jsonObject.getString("type");
        String source = jsonObject.getString("source");
        if (StringUtils.isNotEmpty(type) && StringUtils.isNotEmpty(source)) {
            try {
                AppVersion appVersion = storeService.getNewByType(type, source);
                if (null != appVersion) {
                    Map map = new HashMap();
                    map.put("serverVersion","V"+appVersion.getServerVersion());
                    map.put("appVersion",appVersion.getAppVersion());
                    jsonResult.setData(map);
                    jsonResult.setMsg("请求成功");
                    jsonResult.setCode(0);
                } else {
                    jsonResult.setCode(1);
                    jsonResult.setMsg("没有请求到数据");
                }
            } catch (Exception e) {
                e.printStackTrace();
                jsonResult.setCode(1);
                jsonResult.setMsg("请求参数有误");
                return jsonResult;
            }
        } else {
            jsonResult.setCode(1);
            jsonResult.setMsg("请求参数不能为空");
        }
        return jsonResult;
    }
    /**
     * 测试删除oss文件
     */
    @RequestMapping(value = "/deleteOss",method = RequestMethod.POST)
    public String deleteOss(HttpServletRequest request){
        final String endpoint = PropertyUtils.getProperty("aliyun_endpoint");
        final String accessKeyId = PropertyUtils.getProperty("aliyun_accessKeyId");
        final String accessKeySecret = PropertyUtils.getProperty("aliyun_accessKeySecret");
        final String bucketName = PropertyUtils.getProperty("aliyun_bucketName");
        String serverVersion ="3.17.10.1";
        String type="02";
        Integer size = 2;
        try{
            storeService.deleteOss(endpoint,accessKeyId,accessKeySecret,bucketName,serverVersion,type,size);
        }catch (Exception e){
         e.printStackTrace();
        }

        return "success";
    }
}
